/**
 * 
 */
package com.demo2do.sms.handler.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.demo2do.core.entity.result.HttpResult;
import com.demo2do.core.entity.result.Result;
import com.demo2do.core.http.annotation.Rao;
import com.demo2do.sms.entity.sms.BatchSmsResponse;
import com.demo2do.sms.entity.sms.SmsCompany;
import com.demo2do.sms.entity.sms.SmsRecord;
import com.demo2do.sms.entity.sms.SmsResponse;
import com.demo2do.sms.handler.SmsSender;
import com.demo2do.sms.rao.SmsRao;
import com.demo2do.sms.service.SmsService;

/**
 * @author downpour
 *
 */
@Component("smsSender")
public class SmsDirectSenderImpl implements SmsSender {
    
    private static final Logger logger = LoggerFactory.getLogger(SmsDirectSenderImpl.class);
    
    @Rao
    private SmsRao smsRao;
    
    @Autowired
    private SmsService smsService;
    
    /*
     * (non-Javadoc)
     * @see com.demo2do.sms.handler.SmsSender#send(java.lang.String, java.lang.String, java.lang.String)
     */
    public Result send(String client, String mobiles, String message) {
        
        Result result = new Result();
        
        // 1. validate client in local database
        SmsCompany smsCompany = smsService.loadCompany(client);
        
        if(smsCompany == null || StringUtils.isEmpty(smsCompany.getApikey())) {
            logger.error("#send() get not valida sms company (not exit or empty apikey) with params client[{}] mobiles[{}] message[{}]", client, mobiles, message);
            return result.fail("400").message("请求参数错误！");
        }
        
        // 2. call remote api to send sms ( dispatch different api url )
        
        String[] mobilesArray = StringUtils.split(mobiles, ",");
        List<String> mobileList = Arrays.asList(mobilesArray);
        
        if(CollectionUtils.isNotEmpty(mobileList) && mobileList.size() == 1) {
            
            SmsRecord smsRecord = new SmsRecord(mobiles, message, client);
            smsService.create(smsRecord.initialize());
            
            result = this.send(smsCompany, mobileList.get(0), message);
            
        }else if(CollectionUtils.isNotEmpty(mobileList) && mobileList.size() > 1) {
            
            List<SmsRecord> smsRecords = new ArrayList<SmsRecord>();
            for(String mobile :mobileList) {
                SmsRecord smsRecord = new SmsRecord(mobile, message, client);
                smsRecords.add(smsRecord.initialize());
            }
            smsService.create(smsRecords);
            
            result = this.send(smsCompany, mobileList, message);
        }
        
        return result;
    }

    /**
     * 
     * @param mobile
     * @param message
     * @return
     */
    protected Result send(SmsCompany smsCompany, String mobile, String message) {

        Result result = new Result();
        
        logger.trace("##send() - start send single message to sms server with params mobile [{}] message [{}]", mobile, message);
        
        String apikey = smsCompany.getApikey();
        
        Map<String, Object> raoParams = new LinkedHashMap<String, Object>();
        raoParams.put("mobile", mobile);
        raoParams.put("text", message);
        raoParams.put("apikey", apikey);
        
        HttpResult sendResult = smsRao.singleSend(raoParams);
        
        String body = sendResult.getResponseText();
        logger.trace("##send() - single message send - Get response body [{}].", body);
        
        SmsResponse smsResponse = JSON.parseObject(body, SmsResponse.class);
        result = smsResponse.convertResult();
        
        return result;
    }

    /**
     * 
     * @param mobiles
     * @param message
     * @return
     */
    protected Result send(SmsCompany smsCompany, List<String> mobiles, String message) {
        
        Result result = new Result();
        
        String mobilesString = StringUtils.join(mobiles, ",");
        String apikey = smsCompany.getApikey();
        logger.trace("##send() - start send batch message to sms server with params mobiles[{}], message [{}], and sms amount is [{}]", mobilesString, message, mobiles.size());
        
        Map<String, Object> raoParams = new LinkedHashMap<String, Object>();
        raoParams.put("mobile", mobilesString);
        raoParams.put("text", message);
        raoParams.put("apikey", apikey);
        
        HttpResult sendResult = smsRao.batchSend(raoParams);
        
        String body = sendResult.getResponseText();
        logger.trace("##send() - batch message send - Get response body [{}].", body);
        
        BatchSmsResponse batchSmsResponse = JSON.parseObject(body, BatchSmsResponse.class);
        
        if(batchSmsResponse == null || batchSmsResponse.getTotalCount() == 0) {
            
            logger.trace("##send() - send batch mobiles message failed!");
            result.fail("1").message("批量发送短信失败");
            
        }else {
            logger.trace("##send() - send batch mobiles message success, success amount is [{}]", batchSmsResponse.getTotalCount());
            result.success().message("批量发送短信成功");
        }
            
        return result;
    }
    
}
